#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-11-07 11:41:55
# @Author  : kakarot (kakarotsun@163.com)
# @Link    : http://example.org
# @Version : $Id$

# 遍历文件夹 两种方式 第一种方便控制查看每一层。第二种无脑遍历推荐
# self.dir 绝对路径
# self.res两个list分别存放文件和文件夹
import os
from itertools import *


class dirtree():
    def __init__(self, dira):
        self.dir = dira
        self.res = ({}, [])

    # 遍历entry 分别存入res元组中
    # res[0] key=文件名 value=entry对象
    # res[1] 是存放目录entry对象的list
    def phase_sep(self):
        for each in os.scandir(self.dir):
        	if each.is_dir():
            	self.res[1].append(each.path)
            if each.is_file():
            	self.res[0][each.path]=each

    # 遍历res[1]也就是存放文件夹的list，获取绝对路径
    # 并将dirtree对象存入subdirs
    def phase_subdir(self):
        self.subdirs = []
        for x in self.res[1]:            
            self.subdirs.append(dirtree(x))

    # 报告结果也就是开始运行扫描
    # self.files 表示建立一个文件iter链接 方便链接完整扫描时递归的文件不丢失
    # self.folder 表示建立目录的iter链接 
    def report(self):
        self.phase_sep()
        self.phase_subdir()
        self.files = chain(self.res[0])
        self.folder=chain(self.subdirs)

    def report_full(self):
     	self.report()
        for each in self.subdirs:
            each.report_full()
        	self.files = chain(self.files, each.files)
            self.folder=chain(self.folder,each.folder)

    def demo():
    	dd=dirtree(r'd:\test\1')
    	dd.report_full()
    	# self.folder存放的是dirtree对象 .dir存放的是路径
    	# 打印所有目录
    	for each in dd.folder:
    		print(each.dir)

    	# self.files存放的是文件和文件信息的字典
    	# 打印所有文件
    	for each in dd.files:
    		print(each)

# 堆栈式pop push 遍历文件夹。
class dirtree2():
    def __init__(self, dira=r'd:\test\1'):
        self.dir = [dira]
        self.res = ({}, [])

    def run(self):
        while True:

        	# 如果文件夹没有了就抛异常退出循环
            try:
                folder = self.dir.pop()
            except IndexError:
                break

            for each in os.scandir(folder):
                if each.is_dir():
                	# 文件夹存入res方便以后用
                    self.res[1].append(each.path)
                    # 压入新文件夹
                    self.dir.append(each.path)
                if each.is_file():
                    self.res[0][each.path] = each

    def demo():
    	dd=dirtree(r'd:\test\1')
    	dd.run()
    	# self.folder存放的是dirtree对象 .dir存放的是路径
    	# 打印所有目录
    	for each in dd.res[1]:
    		print(each)

    	# self.files存放的是文件和文件信息的字典
    	# 打印所有文件
    	for each in dd.res[0]:
    		print(each)
